/*
 * @Author: 0x9DEFA478
 * @Date: 2022-06-21 21:25:52
 * @LastEditTime: 2022-06-23 21:35:51
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "IP_SDMMC_SD.h"




/**
 * @brief 微秒延时
 * @param timeUs 微秒为单位的时间
 * @return 无
 */
extern void Delay_us(unsigned int timeUs);

extern void IP_SDMMC_SD_IRQ(void* v);




/**
 * @brief 初始化 IP_SDMMC_SD
 * @param ip_sdmmc_sd 空的IP_SDMMC_SD对象(已分配内存的)
 * @param _sdmmc sdmmc句柄
 * @param Feature 一些特性信息 0为默认值
 * @param SetIrqCallback 设置中断回调方法
 * @param TransferBuffer 传输缓存
 * @param SetIrqCallback 传输缓存大小 必须为2的倍数 单位:4字节
 * @return 无
 */
void IP_SDMMC_SD_Init(IP_SDMMC_SD* ip_sdmmc_sd,SDMMC_TypeDef* _sdmmc,unsigned int Feature,void (*SetIrqCallback)(void (*)(void*),void*)
  ,unsigned int* TransferBuffer,int TransferBufferSize){

  SetIrqCallback(IP_SDMMC_SD_IRQ,ip_sdmmc_sd);

  cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)=_sdmmc;

  cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->POWER=0U;

  cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->CLKCR=Feature&(vIP_SDMMC_SD_Feature_PowerSave|vIP_SDMMC_SD_Feature_NEGEDG_Fall|vIP_SDMMC_SD_Feature_HardwareFlowControl);

  cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->DCTRL=0U;

  cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->ICR=vIP_SDMMC_SD_ICR_ALL;//清除所有中断标志位

  cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->MASK=
    SDMMC_MASK_IDMABTCIE|                                             //IDMA缓冲区传输完成中断
    SDMMC_MASK_CMDSENTIE|                                             //命令发送完成中断(无响应类型才会触发)
    SDMMC_MASK_CMDRENDIE|SDMMC_MASK_CTIMEOUTIE|SDMMC_MASK_CCRCFAILIE| //命令响应相关中断
    SDMMC_MASK_DATAENDIE|SDMMC_MASK_DTIMEOUTIE|SDMMC_MASK_DCRCFAILIE| //数据相关中断
    SDMMC_MASK_TXUNDERRIE|SDMMC_MASK_RXOVERRIE;                       //FIFO错误中断

  Delay_us(2);

  TransferBufferSize/=2;
  cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->IDMABSIZE=TransferBufferSize*4;
  cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->IDMABASE0=(unsigned int)&TransferBuffer[0];
  cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->IDMABASE1=(unsigned int)&TransferBuffer[TransferBufferSize];

  //默认状态
  ip_sdmmc_sd->CLKDIV=1;
  ip_sdmmc_sd->BusWidth=1;
  ip_sdmmc_sd->BlockSize=1;

  ip_sdmmc_sd->CommandIsBusy=0;
  ip_sdmmc_sd->DataIsBusy=0;

}

/**
 * @brief 设置sdmmc_ker_ck到SDMMC_CK的分频 在SDMMC不进行通信时使用
 * @param ip_sdmmc_sd IP_SDMMC_SD对象
 * @param CLKDIV 分频 1 2 4 6 ... 2046 (大于1的分频值只能为2的倍数并且小于等于2046)
 * @return 成功:实际分频值 非正数:失败
 */
int IP_SDMMC_SD_SetCLKDIV(IP_SDMMC_SD* ip_sdmmc_sd,int CLKDIV){

  unsigned int CLKCR;
  unsigned int clkdiv;

  if((ip_sdmmc_sd->CommandIsBusy!=0)||(ip_sdmmc_sd->DataIsBusy!=0)){

    return -1;
  }

  if(ip_sdmmc_sd->CLKDIV==CLKDIV){
    return CLKDIV;
  }

  if(CLKDIV>2046){
    //不支持的分频值
    return -1;
  }

  clkdiv=CLKDIV;
  if(clkdiv==1U){
    clkdiv=0U;
  }else{
    if((clkdiv&0x00000001U)!=0U){
      return -1;
    }
    clkdiv>>=1;
  }

  CLKCR=cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->CLKCR;

  CLKCR=(CLKCR&(~SDMMC_CLKCR_CLKDIV_Msk))|((clkdiv<<SDMMC_CLKCR_CLKDIV_Pos)&SDMMC_CLKCR_CLKDIV_Msk);

  cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->CLKCR=CLKCR;
  ip_sdmmc_sd->CLKDIV=CLKDIV;

  Delay_us(2);

  return CLKDIV;
}

/**
 * @brief 设置位宽 在SDMMC不进行通信时使用
 * @param ip_sdmmc_sd IP_SDMMC_SD对象
 * @param BusWidth 位宽 1, 4, 8, 可选
 * @return 0:成功 其他:失败
 */
int IP_SDMMC_SD_SetBusWidth(IP_SDMMC_SD* ip_sdmmc_sd,int BusWidth){

  unsigned int CLKCR;

  if((ip_sdmmc_sd->CommandIsBusy!=0)||(ip_sdmmc_sd->DataIsBusy!=0)){

    return -1;
  }

  if(ip_sdmmc_sd->BusWidth==BusWidth){
    return 0;
  }

  CLKCR=cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->CLKCR;

  switch(BusWidth){
    case 1:
      CLKCR&=(~SDMMC_CLKCR_WIDBUS_Msk);
      break;
    case 4:
      CLKCR&=(~SDMMC_CLKCR_WIDBUS_Msk);
      CLKCR|=(0x1U<<SDMMC_CLKCR_WIDBUS_Pos);
      break;
    case 8:
      CLKCR&=(~SDMMC_CLKCR_WIDBUS_Msk);
      CLKCR|=(0x2U<<SDMMC_CLKCR_WIDBUS_Pos);
      break;
    default:
      return -1;
  }
  cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->CLKCR=CLKCR;
  ip_sdmmc_sd->BusWidth=BusWidth;

  Delay_us(2);

  return 0;
}

/**
 * @brief 设置时钟状态
 * @param ip_sdmmc_sd IP_SDMMC_SD对象
 * @param IsOn 0:掉电 其他:提供时钟
 * @return 无
 */
void IP_SDMMC_SD_SetPower(IP_SDMMC_SD* ip_sdmmc_sd,int IsOn){

  if(IsOn==0){
    cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->POWER=0U;
  }else{
    cIP_SDMMC_SD_SDMMC(ip_sdmmc_sd)->POWER=SDMMC_POWER_PWRCTRL_Msk;
  }
  Delay_us(2);
  
}



